package com.sangshen.ad_suyi_flutter_sdk;

import android.app.Activity;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import java.util.HashMap;
import java.util.Map;

import cn.admobiletop.adsuyi.ADSuyiSdk;
import cn.admobiletop.adsuyi.config.ADSuyiInitConfig;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.StandardMethodCodec;
import io.flutter.plugin.platform.PlatformViewRegistry;

public class ADSuyiMobileAdsPlugin implements FlutterPlugin, ActivityAware, MethodChannel.MethodCallHandler {

    @Nullable
    private FlutterPluginBinding pluginBinding;
    @Nullable
    private AdInstanceManager instanceManager;

    private final Map<String, NativeAdFactory> nativeAdFactories = new HashMap<>();

    public static boolean registerNativeAdFactory(FlutterEngine engine, String factoryId) {
        final ADSuyiMobileAdsPlugin gmaPlugin =
                (ADSuyiMobileAdsPlugin) engine.getPlugins().get(ADSuyiMobileAdsPlugin.class);
        return registerNativeAdFactory(gmaPlugin, factoryId);
    }

    private static boolean registerNativeAdFactory(ADSuyiMobileAdsPlugin plugin, String factoryId) {
        if (plugin == null) {
            final String message =
                    String.format(
                            "Could not find a %s instance. The plugin may have not been registered.",
                            ADSuyiMobileAdsPlugin.class.getSimpleName());
            throw new IllegalStateException(message);
        }

        return plugin.addNativeAdFactory(factoryId);
    }

    private boolean addNativeAdFactory(String factoryId) {
        if (nativeAdFactories.containsKey(factoryId)) {
            final String errorMessage =
                    String.format(
                            "A NativeAdFactory with the following factoryId already exists: %s", factoryId);
            Log.e(ADSuyiMobileAdsPlugin.class.getSimpleName(), errorMessage);
            return false;
        }

        nativeAdFactories.put(factoryId, null);
        return true;
    }

    /**
     * Public constructor for the plugin. Dependency initialization is handled in lifecycle methods
     * below.
     */
    public ADSuyiMobileAdsPlugin() {}

    /** Constructor for testing. */
    @VisibleForTesting
    protected ADSuyiMobileAdsPlugin(
            @Nullable FlutterPluginBinding pluginBinding, @Nullable AdInstanceManager instanceManager) {
        this.pluginBinding = pluginBinding;
        this.instanceManager = instanceManager;
    }

    public interface NativeAdFactory {

    }

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
        pluginBinding = binding;
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {

    }

    @Override
    public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
        initializePlugin(
                binding.getActivity(),
                pluginBinding.getBinaryMessenger(),
                pluginBinding.getPlatformViewRegistry());
    }

    private void initializePlugin(Activity activity, BinaryMessenger messenger, PlatformViewRegistry platformViewRegistry) {
        final MethodChannel channel =
                new MethodChannel(
                        messenger,
                        "ad_suyi_sdk",
                        new StandardMethodCodec(new AdMessageCodec()));
        channel.setMethodCallHandler(this);
        instanceManager = new AdInstanceManager(activity, messenger, channel);

        pluginBinding.getPlatformViewRegistry().registerViewFactory("ADSuyiAdView", new ADSuyiAdViewFactory(instanceManager));
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {

    }

    @Override
    public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {

    }

    @Override
    public void onDetachedFromActivity() {

    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        switch (call.method) {
            case "initSdk":
                // Internal init. This is necessary to cleanup state on hot restart.
                instanceManager.disposeAllAds();
                // 初始化ADSuyi广告SDK
                ADSuyiSdk.getInstance().init(
                    instanceManager.activity,
                    new ADSuyiInitConfig.Builder()
                        // 设置APPID
                        .appId(ADSuyiDemoConstant.APP_ID)
                        // 是否开启Debug，开启会有详细的日志信息打印，如果用上ADSuyiToastUtil工具还会弹出toast提示。
                        // TODO 注意上线后请置为false
                        .debug(BuildConfig.DEBUG)
                        // 是否同意隐私政策
                        .agreePrivacyStrategy(true)
                        // 是否过滤第三方平台的问题广告（例如: 已知某个广告平台在某些机型的Banner广告可能存在问题，如果开启过滤，则在该机型将不再去获取该平台的Banner广告）
                        .filterThirdQuestion(true)
                        // 是否同意使用oaid
                        .isCanUseOaid(true)
                        // 如果开了浮窗广告，可设置不展示浮窗广告的界面，第一个参数为是否开启默认不展示的页面（例如:激励视频播放页面），第二可变参数为自定义不展示的页面
                        .floatingAdBlockList(false, "cn.admobiletop.adsuyidemo.activity.SplashAdActivity")
                        .build()
                );
                result.success(null);
                break;
            case "loadSplashAd":
                final FlutterSplashAd splashAd =
                        new FlutterSplashAd.Builder()
                                .setManager(instanceManager)
                                .setAdPosId(call.<String>argument("posId"))
                                .build();
                instanceManager.trackAd(splashAd, call.<Integer>argument("adId"));
                splashAd.load();
                result.success(null);
                break;
            case "loadBannerAd":
                final FlutterBannerAd bannerAd =
                        new FlutterBannerAd.Builder()
                                .setManager(instanceManager)
                                .setAdPosId(call.<String>argument("posId"))
                                .setAdWidth(call.<Double>argument("adWidth"))
                                .setAdHeight(call.<Double>argument("adHeight"))
                                .build();
                instanceManager.trackAd(bannerAd, call.<Integer>argument("adId"));
                bannerAd.load();
                result.success(null);
                break;
            case "loadNativeAd":
                final FlutterNativeAd nativeAd =
                        new FlutterNativeAd.Builder()
                                .setManager(instanceManager)
                                .setAdPosId(call.<String>argument("posId"))
                                .setAdWidth(call.<Double>argument("adWidth"))
                                .setAdHeight(call.<Double>argument("adHeight"))
                                .build();
                instanceManager.trackAd(nativeAd, call.<Integer>argument("adId"));
                nativeAd.load();
                result.success(null);
                break;
            case "loadIntertitialAd":
                final FlutterInterstitialAd interstitialAd =
                        new FlutterInterstitialAd.Builder()
                                .setManager(instanceManager)
                                .setAdPosId(call.<String>argument("posId"))
                                .build();
                instanceManager.trackAd(interstitialAd, call.<Integer>argument("adId"));
                interstitialAd.load();
                result.success(null);
                break;
            case "loadRewardAd":
                final FlutterRewardVodAd rewardVodAd =
                        new FlutterRewardVodAd.Builder()
                                .setManager(instanceManager)
                                .setAdPosId(call.<String>argument("posId"))
                                .build();
                instanceManager.trackAd(rewardVodAd, call.<Integer>argument("adId"));
                rewardVodAd.load();
                result.success(null);
                break;
            case "loadFullScreenVodAd":
                final FlutterFullScreenVodAd fullScreenVodAd =
                        new FlutterFullScreenVodAd.Builder()
                                .setManager(instanceManager)
                                .setAdPosId(call.<String>argument("posId"))
                                .build();
                instanceManager.trackAd(fullScreenVodAd, call.<Integer>argument("adId"));
                fullScreenVodAd.load();
                result.success(null);
                break;
            case "showIntertitialAd":
            case "showRewardAd":
            case "showFullScreenVodAd":
                FlutterAd flutterFullScreenVodAd = instanceManager.adForId(call.<Integer>argument("adId"));
                if (flutterFullScreenVodAd instanceof FlutterAd.FlutterOverlayAd) {
                    ((FlutterAd.FlutterOverlayAd)flutterFullScreenVodAd).show();
                }
                result.success(null);
                break;
        }
    }
}
